package com.gouqi.mall.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gouqi.mall.domain.User;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Token生成工具类
 * @author :小费
 */
public class TokenUtils {

    //公共密钥客户端不会知道
    public static String SECRET="FreeMaNong";

    /**
     * 创建token
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createToken(User user) throws UnsupportedEncodingException {
        //签名发布时间（英文时间）
        Date iatDate=new Date();
        System.out.println("签名发布时间："+iatDate);

        //设置签名过期时间  1分钟
        Calendar nowTime=Calendar.getInstance();
        nowTime.add(Calendar.MINUTE,60);
        Date expiresDate = nowTime.getTime();
        System.out.println("签名过期时间："+expiresDate);

        Map<String,Object> map=new HashMap<String, Object>();
        map.put("alg","HS256");//设置算法 为HS256
        map.put("type","JWT");//设置类型为JWT
        String token= JWT.create().withHeader(map)
                .withClaim("name",user.getName())
                .withClaim("age",user.getAge())
                .withClaim("password",user.getPassword())
                .withClaim("account",user.getAccount())
                .withIssuedAt(iatDate)//设置签发时间
                .withExpiresAt(expiresDate)//设置过期时间 过期时间大于签发时间
                .sign(Algorithm.HMAC256(SECRET));//用公共密钥加密
        System.out.println("打印token：");
        System.out.println(token);
        return token;
    }
    /**
     * 验证token
     * @param token
     * @return
     * @throws UnsupportedEncodingException
     */
    public static Map<String,Claim> verifyToken(String token) throws UnsupportedEncodingException {
        JWTVerifier verifier =JWT.require(Algorithm.HMAC256(SECRET)).build();//用公共密钥解密验证
        DecodedJWT jwt= null;
        try{
            jwt=verifier.verify(token);
        }catch (Exception e) {
            System.out.println("登录凭证已过期，请重新登录!");
            Map<String, Claim> objectObjectMap = new HashMap<String, Claim>();
            return objectObjectMap;
            //throw new RuntimeException("登录凭证已过期，请重新登录");
        }
        return jwt.getClaims();
    }

    /**
     * 获取request
     * @return
     */
    public static HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        return requestAttributes == null ? null : requestAttributes.getRequest();
    }

    /**
     * 从token中获取用户id
     * @return
     */
    public static String getTokenUserId() {
        // 从 http 请求头中取出 token
        String token = getRequest().getHeader("token");
        String userId = JWT.decode(token).getAudience().get(0);
        return userId;
    }
}
